package com.apestech.api.workflow.lib.app;

import com.alibaba.druid.pool.DruidDataSource;
import com.apestech.api.workflow.extend.CounterSign;
import com.apestech.api.workflow.extend.FlowDatabase;
import com.apestech.api.workflow.lib.FlowUtil;
import com.apestech.api.workflow.lib.element.FlowExecute;
import com.apestech.api.workflow.lib.element.FlowTask;
import com.apestech.api.workflow.lib.element.WorkProcessEngine;
import com.apestech.framework.db.SqlSession;
import com.apestech.framework.json.JSON;
import com.apestech.framework.json.JSONArray;
import com.apestech.framework.json.JSONObject;
import com.apestech.framework.util.DBUtil;

/**
 * 会签场景
 *
 * @author hup
 * @create 2018-07-21-14:35
 */
public class CounterSignApp extends FlowUtil{

    private WorkProcessEngine engine;
    private SqlSession session;
    private FlowTask flowTask;
    private JSONObject input;
    private String processInstanceId;
    private String state;
    private String taskId;
    private String taskName;
    private JSONObject taskMap;
    private String nodeUserId;
    private String nodeUserName;
    private String userId;
    private String userName;

    public CounterSignApp(WorkProcessEngine engine, JSONObject input) throws Exception {
        this.engine=engine;
        this.session= DBUtil.getSession(this.engine.getDataSource());
        this.session.setConnection(this.engine.getConnection());
        this.input=input;
        this.processInstanceId=input.getString("processInstanceId");
        this.taskId=input.getString("taskId");
        if(this.processInstanceId==null && this.taskId==null){
            throw new Exception("流程ID或任务ID不允许为空！");
        }
        this.input.put("userId", input.getString("loginUserId"));
        this.input.put("userName", input.getString("loginUserName"));
        preInputValidate(this.input, true);
        this.flowTask= getFlowTask(this.engine, this.input);
        if(this.flowTask.getTask().isSuspended()){
            throw new Exception("该任务为挂起状态，不允许做会签相关操作！");
        }
        this.input.put("processInstanceId", flowTask.getProcessInstanceId());
        this.state=flowTask.getState();
        this.taskId=flowTask.getTask().getId();
        this.taskName=flowTask.getTask().getName();
        this.taskMap=getTaskMap(this.engine, this.taskId, this.input);
        this.nodeUserId=this.taskMap.getString("counter_userId");
        this.nodeUserName=this.taskMap.getString("counter_userName");
        this.userId=this.input.getString("userId");
        this.userName=this.input.getString("userName");
    }

    /**
     * 会签发起
     * @throws Exception
     */
    public void startCounterSign() throws Exception {
        if(input.get("userlist")==null){
            throw new Exception("会签必须选择人员列表！");
        }
        if(!("claim".equals(state) || "addSign".equals(state) || "complete".equals(state)|| "assgin".equals(state) )){
            throw new Exception("当前状态不允许做会签发起操作！");
        }
        if("assgin".equals(state)){
            engine.getTaskService().claim(flowTask.getTask().getId(), input.getString("loginUserId"));
            flowTask.setState("claim");
            flowTask= getFlowTask(engine,  this.input);
        }
        if(!input.getString("loginUserId").equals(flowTask.getTask().getAssignee())){
            throw new Exception("当前结点发起人["+input.getString("loginUserId")+"]不是结点经办人["+flowTask.getTask().getAssignee()+"]，请重新发起！");
        }
        nodeUserId=input.getString("loginUserId");
        nodeUserName=input.getString("loginUserName");
        JSONArray userlist= JSON.toJSONArray(input.get("userlist"));
        CounterSign sign= new CounterSign(userlist);
        input.put("counterUserId",sign.getPersonId());
        input.put("counterUserName",sign.getPersonName());
        taskMap.put("counter_finish", sign.getFinish());
        taskMap.put("counter_userlist", sign.getUserlistStr());
        taskMap.put("counter_order", sign.getSignOrder());
        taskMap.put("counter_userId", nodeUserId);
        taskMap.put("counter_userName", nodeUserName);
        FlowExecute exec=new FlowExecute(engine);
        if(flowTask.getTask().getAssignee()!=null){
            exec.unClaimTask(taskId);
        }
        exec.deleteTaskAllUser(taskId);
        exec.assignTaskToUser(taskId, sign.getUnFinishUser());
        engine.getTaskService().setVariables(taskId, taskMap);
        if("addSign".equals(state)){
            flowTask.setState("addSign-counterSign");
            writeTaskDb(engine, session, input, taskId, taskName, ExtendDbType.ADD_START_COUNTER_SIGN);
        } else {
            flowTask.setState("counterSign");
            writeTaskDb(engine, session, input, taskId, taskName, ExtendDbType.START_COUNTER_SIGN);
        }
    }

    /**
     * 会签回应
     * @throws Exception
     */
    public void execCounterSign() throws Exception {
        if(state.indexOf("counterSign")<0){
            throw new Exception("当前状态不加会签中，不允许做会签回应操作！");
        }
        CounterSign sign= new CounterSign();
        sign.setFinish(taskMap.getIntValue("counter_finish"));
        sign.setUserlistStr(taskMap.getString("counter_userlist"));
        sign.setSignOrder(taskMap.getString("counter_order"));
        sign.exec(userId);
        FlowExecute exec=new FlowExecute(engine);
        exec.deleteTaskAllUser(taskId);

        if(sign.isFinish()){
            //exec.assignTaskToUser(taskId, nodeUserId);
            if(state.indexOf("addSign")>=0){
                flowTask.setState("addSign");
            } else {
                flowTask.setState("claim");
            }
            nodeUserId=getCommission(engine, nodeUserId);
            exec.claimTask(taskId, nodeUserId);
            engine.getTaskService().removeVariable(taskId, "counter_finish");
            engine.getTaskService().removeVariable(taskId, "counter_userlist");
            engine.getTaskService().removeVariable(taskId, "counter_order");
            engine.getTaskService().removeVariable(taskId, "counter_userId");
            engine.getTaskService().removeVariable(taskId, "counter_userName");
        } else {
            taskMap.put("counter_finish", sign.getFinish());
            taskMap.put("counter_userlist", sign.getUserlistStr());
            taskMap.put("counter_order", sign.getSignOrder());
            exec.assignTaskToUser(taskId, sign.getUnFinishUser());
            engine.getTaskService().setVariables(taskId, taskMap);
        }
        if(state.indexOf("addSign")>0){
            writeTaskDb(engine, session, input, taskId, taskName, ExtendDbType.ADD_COUNTER_SIGN);
        } else {
            writeTaskDb(engine, session, input, taskId, taskName, ExtendDbType.COUNTER_SIGN);
        }
    }

    public JSONObject getInput() {
        return input;
    }

}
